package containerlogistik.implementation;

import java.util.Objects;
import containerlogistik.interfaces.TimeDiff;

public class TimeDiffInS extends AbstractValue<TimeDiff> implements TimeDiff {

    private double begin;
    private double end;
    private double seconds;

    private TimeDiffInS(double begin, double end) {
        this.begin = begin;
        this.end = end;
        this.calcValue();
    }

    static TimeDiff valueOf(double begin, double end) {
        return new TimeDiffInS(begin, end);
    }

    @Override
    public double s() {
        return this.seconds;
    }

    /**
     * Calculates the time difference between begin and end time.
     */
    private void calcValue() {
        this.seconds = (this.end() - this.begin());

    }

    @Override
    public double begin() {
        return this.begin;
    }

    @Override
    public void begin(Double begin) {
        this.begin = Objects.requireNonNull(begin, "Begin can not be null!");
        this.calcValue();
    }

    @Override
    public double end() {
        return this.end;
    }

    @Override
    public void end(Double end) {
        this.end = Objects.requireNonNull(end, "End can not be null!");
        this.calcValue();
    }

    @Override
    public boolean isZero() {
        return (this.equals(Values.ZERO_TIMEDIFF));
    }

    @Override
    public boolean isValid() {
        return true;
    }

    @Override
    public String toString() {
        return "TimeDiffInS{" + "begin=" + this.begin() + ","
                + " end=" + this.end() + '}';
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final TimeDiffInS other = (TimeDiffInS) obj;
        if (Double.doubleToLongBits(this.begin()) != Double.doubleToLongBits(other.begin())) {
            return false;
        }
        if (Double.doubleToLongBits(this.end()) != Double.doubleToLongBits(other.end())) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        return hashDouble(this.begin());
    }

    @Override
    public int compareTo(TimeDiff o) {
        return Double.compare(this.s(), o.s());
    }

    @Override
    public TimeDiff add(TimeDiff value) {
        return Values.timeDiffInS(this.begin(), (this.begin() + this.s() + value.s()));
    }

    @Override
    public TimeDiff sub(TimeDiff value) {
        return Values.timeDiffInS(this.begin(), (this.begin() + this.s() - value.s()));
    }

    @Override
    public TimeDiff mul(double factor) {
        return Values.timeDiffInS(this.begin(), ((this.begin() + this.s()) * factor));
    }

    @Override
    public TimeDiff div(double factor) {
        return Values.timeDiffInS(this.begin(), ((this.begin() + this.s()) / factor));
    }

    @Override
    public TimeDiff inverse() {
        return Values.timeDiffInS(this.begin(), (this.begin() + this.s()));
    }

    @Override
    public double div(TimeDiff value) {
        return (this.s() / value.s());
    }
}
